/**
 * 
 */
package bingo.validation.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import bingo.validation.IValidator;
import bingo.validation.ValidationException;
import bingo.validation.ValidationResult;

/**
 * 基于Annotation的IValidator抽象类，相比IValidator接口，
 * AnnotationValidator多了一个setCheck()的方法来获取对应的Check内容
 */
public abstract class AnnotationValidator<CheckAnnotation extends Annotation> implements IValidator {

	protected String message;
	
	protected Map<String, String> variables = new HashMap<String, String>();

	/*
	 * (non-Javadoc)
	 * @see bingo.validation.IValidator#setMessage(java.lang.String)
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	public void initialize(CheckAnnotation check) {
		for(Method method: check.annotationType().getDeclaredMethods()){
			if(method.getName().equals("message")){
				try {
					String message = (String) method.invoke(check);
					if (null != message && !"".equals(message.trim())) {
						this.setMessage(message);
					}
				} catch (final Exception e) {
					//TODO: log warning exception here
				}				
			}else{//添加变量定义
				try {
					Object var = method.invoke(check);
					if (null != var && (var.getClass() == String.class || var.getClass().isPrimitive())) {
						this.variables.put(method.getName(), String.valueOf(var));
					}
				} catch (final Exception e) {
					
				}
			}
		}
	}
	
	public final ValidationResult validate(Object bean, Object objectToValidate, Object valueToValidate) throws ValidationException {
		if(this.variables.get("name") == null){
			if(objectToValidate instanceof Field){
				this.variables.put("name", ((Field)objectToValidate).getName());
			}else{
				this.variables.put("name", objectToValidate.getClass().getSimpleName());
			}
		}
		
		return doValidate(objectToValidate,valueToValidate);
	}

	protected String formatMessage(){
		if(null == message){
			return "";
		}else{
			if(message.indexOf("{") < 0){
				return message;
			}else{
				String formatedMessage = message;
				for(String key : variables.keySet()){
					formatedMessage = formatedMessage.replaceAll("\\{" + key + "}", variables.get(key));
				}
				return formatedMessage;	
			}
		}
	}
	
	protected abstract ValidationResult doValidate(Object objectToValidate, Object valueToValidate) throws ValidationException;
}
